package com.chenziruo.securitydemo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration//配置类
//@EnableWebSecurity//开启SpringSecurity的自定义配置(在SpringBoot中可以省略此注解)
@EnableMethodSecurity// 开启基于方法的授权
public class WebSecurityConfig {


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //authorizeRequests()：开启授权保护
        //anyRequest()：对所有请求开启授权保护
        //authenticated()：已认证请求会自动被授权
        http.authorizeRequests(authorize -> authorize
//                .regexMatchers("/user/add").hasAnyAuthority("USER_ADD")
//                .regexMatchers("/user/list").hasAnyAuthority("USER_LIST")
//                .regexMatchers("/user/*").hasRole("ADMINISTRATOR")

                .anyRequest().authenticated())
                .formLogin(form -> {
                    form
                            .loginPage("/login").permitAll() //登录页面无需授权即可访问
                            .usernameParameter("username") //自定义表单用户名参数，默认是username
                            .passwordParameter("password") //自定义表单密码参数，默认是password
                            .failureUrl("/login?error") //登录失败的返回地址
                            .successHandler(new MyAuthenticationSuccessHandler())//认证成功时的处理
                            .failureHandler(new MyAuthenticationFailureHandler())//认证失败时的处理
                    ;
                })
                .logout(logout -> {
                    logout.logoutSuccessHandler(new MyLogoutSuccessHandler());//注销成功时候的处理
                })//表单授权方式
                .exceptionHandling(exception -> {
                    exception.authenticationEntryPoint(new MyAuthenticationEntryPoint());//请求未认证的处理
                    exception.accessDeniedHandler(new MyAccessDeniedHandler());
                })
//                .httpBasic(withDefaults())//基本授权方式
        ;
        // //关闭csrf攻击防御
        http.csrf((csrf) -> {
            csrf.disable();
        });
        //会话管理
        http.sessionManagement(session -> {
            session.maximumSessions(1)//针对同一个账号最多几个客户端登录，会把之前登录的账号踢出
                    .expiredSessionStrategy(new MySessionInformationExpiredStrategy());
        });
        // 跨域
        http.cors(withDefaults());
        return http.build();
    }

//    @Bean
//    public UserDetailsService userDetailsService(){
//        //创建基于内存的用户信息管理器
//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//        //使用manager管理UserDetails对象
//        manager.createUser(
//                //创建UserDetails对象，用于管理用户名、用户密码、用户角色、用户权限等角色
//                User.withDefaultPasswordEncoder().username("kkk").password("123").roles("USER").build());
//        return manager;
//    }

//    @Bean
//    public UserDetailsService userDetailsService(){
//        //创建基于数据库的用户信息管理器
//        DBUserDetailsManager manager = new DBUserDetailsManager();
//        return manager;
//    }
}